﻿using System;
using NUnit.Framework;
using NewsMine.Logging;
using System.IO;
using NLog;
using NLog.Config;
using NLog.Targets;
using System.Threading;

namespace NewsMine.Logging.Test
{
    [TestFixture] 
    public class TestNewsMineLog
    {
        INewsMineLogger _logger;

        /// <summary>
        /// 
        /// </summary>
        [SetUp]
        public void Init()
        {

            // Step 1. Create configuration object 
            LoggingConfiguration config = new LoggingConfiguration();


            FileTarget fileTarget = new FileTarget();
            config.AddTarget("file", fileTarget);

            // Step 3. Set target properties             
            fileTarget.FileName = "${basedir}/file1.txt";
            fileTarget.Layout = "${date:format=HH\\:MM\\:ss} | ${logger} | ${message}";

            // Step 4. Define rules
            LoggingRule rule2 = new LoggingRule("*",LogLevel.FromOrdinal(0) ,fileTarget);
            config.LoggingRules.Add(rule2);

            // Step 5. Activate the configuration
            LogManager.Configuration = config;

            _logger = NewsMineLogManager.GetLogger("TestNewsMineLog",true);            
        }

        [Test]
        public void TestDebug()
        {
            _logger.Debug("Test debug");
            AssertLogFileAndDelete("file");
        }

        [Test]
        public void TestDebugException()
        {
            _logger.DebugException("Test Debug Exception", new NullReferenceException("Error to Debug Info"));
            AssertLogFileAndDelete("file");
        }

        [Test]
        public void TestInfo()
        {
            _logger.Info("Test Info");            
            AssertLogFileAndDelete("file");
        }

        [Test]
        public void TestInfoException()
        {
            _logger.InfoException("Test Info Exception", new NullReferenceException("Error to Test Info"));
            AssertLogFileAndDelete("file");
        }

        [Test]
        public void TestError()
        {
            _logger.Error("Test Error");            
            AssertLogFileAndDelete("file");
        }

        [Test]
        public void TestErrorException()
        {
            _logger.ErrorException("Test ErrorException", new NullReferenceException("Error to TestErrorEx "));
            AssertLogFileAndDelete("file");
        }

        [Test]
        public void TestFatal()
        {
            _logger.Fatal("Test Fatal");
            AssertLogFileAndDelete("file");
        }

        [Test]
        public void TestFatalException()
        {
            _logger.FatalException("Test FatalException", new NullReferenceException("Error to TestFatalEx "));
            AssertLogFileAndDelete("file");
        }

        [Test]
        public void TestWarn()
        {
            _logger.Warn("Test Warn");
            AssertLogFileAndDelete("file");
        }

        [Test]
        public void TestWarnException()
        {
            _logger.WarnException("Test WarnException", new NullReferenceException("Error to TestWarnlEx "));
            AssertLogFileAndDelete("file");
        }


        private void AssertLogFileAndDelete(string fileTargetName)
        {
            string fileName = _logger.GetLogFilePath(fileTargetName);
            FileStream fs = null ;
            _logger.Debug(" FileName Got is  " + fileName);
            try
            {
                _logger.Debug("Filename :" + fileName.Replace("'", "").Replace("\\", "\\\\"));
                fs = File.Open(fileName.Replace("'", "").Replace("\\","\\\\"), FileMode.Open, FileAccess.Read);                
                Assert.True(fs.Length > 0);
                fs.Close();
                fs.Dispose();
                //File.Delete(fileName);
                
            }
            catch (Exception ex)
            {
                _logger.Error("file error st : "+ ex.Message);
                //Assert.Fail("Not able to open log file");           
                Assert.IsNotNull(fs);
                fs.Close();
                fs.Dispose();
            }            
            
            
        }

        [Test]
        public void TestLogConcurrently()
        {
            _logger.Debug("Test multithread: base thread: debug 1");
            var child = new Thread(
               o => { _logger.Debug("Test multithread: child thread: debug 2");  }
               );
            child.Start();
            _logger.Debug("Test multithread: base thread:  debug 3");
            //child.Join();

            _logger.Debug("Test multithread: base thread:  debug 4");

            var child2 = new Thread(
               o => { _logger.Debug("Test multithread: child2 thread:  debug 5"); }
               );
            child2.Start();
            _logger.Debug("Test multithread: base thread:  debug 6");
            //child2.Join();

            
        }

    }
}
